#!/usr/bin/python
#
# DESCRIPTION
#
#   This script implements the delete command for the external Linux/UNIX 
#   application.
#
#   The delete command is an input command. The IDM engine sends the delete 
#   command to the subscriber to request that the external application delete
#   an entry.  The delete command must contain an ASSOCIATION element.
#
#
# VARIABLES
#
#   SRC_DN
#     Specifies the distinguished name of the entry to delete, in the name 
#     space of eDirectory.
#
#   DEST_DN
#     Spceifies the distinguished name of the entry in the name space of the 
#     receiver.
#
#   DEST_ENTRY_ID
#     Spceifies the entry ID for the entry in the name space of the receiver.
#
#   CLASS_NAME
#     Specifies the base class of the entry being deleted.
#
#   EVENT_ID
#     Specifies an identifier used to identify a particular instance of the 
#     command.
#
#   ASSOCIATION
#     Specifies the unique identifier for the entry in the external application.
#
#
# REPLY FORMAT
#
#    The receiving application should respond to the modify with a STATUS
#    and an optional STATUS_MESSAGE which can be returned for IDM engine 
#    processing and logging facilities.
#
#    The format for returning STATUS and STATUS_MESSAGE are as follows:
#
#      status_<level>("<optional message>")
#
#        <level> may be one of the following values:
#        * success
#        * warning
#        * error
#        * retry
#        * fatal
#
#      Note:  fatal will shutdown the driver, retry will retry the event
#             later on.
#

# include the IDM Library
from idmlib import *
from globals import *

import MySQLdb
import sys
import os
import md5

g = GlobalSettings()

logger("debug", "delete.py", " deleting ")
trace(" delete.py  ")

class_name = idmgetvar("CLASS_NAME")

# determine if we even want to delete anything
enable_deletes = idmgetdrvvar("enable-deletes")

if (enable_deletes != 'true'):
    logger("debug", "delete.py", " deletes are disabled ")
    status_warning("Deletes are disabled.  Exiting.")
    sys.exit(0)
logger("debug", "delete.py", " deletes are enabled ")

# retrieve the provisioning user and password & md5secret from the driver
md5secret = idmgetdrvvar("md5secret");
mysqlprovuser = idmgetdrvvar("mysqlprovuser");
mysqlprovpw = idmsubgetnamedpassword("mysqlprovpw");

enable_backups = idmgetdrvvar("enable-backups")
enable_obscure_filenames = idmgetdrvvar("enable-obscure-filenames")

# Retrieve additional information about the event 

SRC_DN = idmgetvar("SRC_DN")
SRC_ENTRY_ID = idmgetvar("SRC_ENTRY_ID")
EVENT_ID = idmgetvar("EVENT_ID")
ASSOCIATION = idmgetvar("ASSOCIATION")

# Get database name and host out of the association
(dbname,dbhost,dbport) = ASSOCIATION.split('@')

# Check input validity
if (dbname == ''):
    status_error("Missing database name to delete!")
    sys.exit(0)
if (dbhost == ''):
    status_error("Missing database host!")
    sys.exit(0)
if (dbport == ''):
    status_error("Missing database port!")
    sys.exit(0)
if (mysqlprovuser == ''):
    status_error("Missing mysql provisioning user!")
    sys.exit(0)
if (mysqlprovpw == ''):
    status_error("Missing mysql provisioning password!")
    sys.exit(0)

### This will be needed as an int later
dbport = int(dbport)


### If we've enabled backups, make one, otherwise go on..
if (enable_backups == 'true'):

    ### Dump file using mysqldump
    backupdir = g.defaults['backupdir']
    mysqldump = g.defaults['mysqldump']

    if (enable_obscure_filenames == 'true'):
       dumpfilename = md5.new(dbname + md5secret).hexdigest() + ".sql"
    else:
       dumpfilename = dbname + ".sql"

    dumpstr = mysqldump + " --opt -h" + dbhost + " -u " + mysqlprovuser + " -p" + mysqlprovpw + " " + \
          dbname + " > " + backupdir + dumpfilename

    #### Need to add error checking here.  Should probably do this with subprocess module
    os.system(dumpstr)

# Get a Database Connection
try:
    conn = MySQLdb.connect (host = dbhost,
                             user = mysqlprovuser,
                             passwd = mysqlprovpw,
                             port = dbport)

except MySQLdb.Error, e:
    status_error("MYSQL ERROR %d: %s" % (e.args[0], e.args[1]))
    sys.exit (0)
except KeyError:
    status_error("Key Error:  Most likely cause is using an invalid dbhost, or \
    missing privileged user/pass for dbhost")    
    sys.exit (0)
except:
    status_error("An unexpected error occured while trying to connect mysql on: " + dbhost)
    sys.exit(0)


# Make sure the database already exists, then if not, somethings wrong so lets fail.
try:
     cursor = conn.cursor ()
     cursor.execute ("SHOW DATABASES LIKE '" + MySQLdb.escape_string(dbname) + "'");
     if (cursor.rowcount > 0):
       pass # The database is there, we are good to keep going 
     else:
        cursor.close ()
        status_error("Attempting to delete database: (" + dbname + ").  It does not exist!")
        sys.exit(0)

     ### select the mysql administrative database;
     cursor.execute ("USE mysql;")

     ### select user,host from db where db = association
     cursor.execute ("SELECT user,host from db where db = '" + MySQLdb.escape_string(dbname) + "';")

     results = cursor.fetchall()

     ### for each entry we get back
     for row in results: 

       user = row[0]
       host = row[1]

       ### drop the user@host
       cursor.execute("DROP USER "+ MySQLdb.escape_string(user) + "@'" + MySQLdb.escape_string(host) + "';")

     ### end for
  
     ### drop the database
     cursor.execute("DROP DATABASE " + MySQLdb.escape_string(dbname) + ";")

     ### clean up
     cursor.close ()
        
except MySQLdb.Error, e:
    cursor.close ()
    status_error("MYSQL ERROR %d: %s" % (e.args[0], e.args[1]))
    sys.exit (0)

### And we're out
status_success("OK")
